From 26b7063388a28335dd569bb9be2d2d70bb0fcd84 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Tue, 28 Nov 2000 08:44:02 +0000 Subject: [PATCH] Implement configure events and correct enter/leave notification. --- ChangeLog | 26 ++++ ChangeLog.pre-2-0 | 26 ++++ ChangeLog.pre-2-10 | 26 ++++ ChangeLog.pre-2-2 | 26 ++++ ChangeLog.pre-2-4 | 26 ++++ ChangeLog.pre-2-6 | 26 ++++ ChangeLog.pre-2-8 | 26 ++++ gdk/linux-fb/gdkinput-ps2.c | 228 ++++++++++++++++++++--------------- gdk/linux-fb/gdkmain-fb.c | 10 +- gdk/linux-fb/gdkprivate-fb.h | 9 +- gdk/linux-fb/gdkwindow-fb.c | 70 ++++++++++- 11 files changed, 389 insertions(+), 110 deletions(-) diff --git a/ChangeLog b/ChangeLog index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 191ac8c7d4..b1d302cbf4 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,29 @@ +2000-11-28 Alexander Larsson + + * gdk/linux-fb/gdkinput-ps2.c: + Implement correct EnterNotify/LeaveNotify: + (gdk_fb_window_send_crossing_events): New function that sends + all GdkCrossingEvents from the last mouse-window to the specified + destination. + (gdk_fb_window_visibility_crossing): Removed function. + (handle_mouse_input): Use gdk_fb_window_send_crossing_events() + (send_button_event, gdk_fb_cursor_reset): Use gdk_window_at_pointer + instead of gdk_window_get_pointer() for better readability. + + * gdk/linux-fb/gdkmain-fb.c (gdk_fb_pointer_grab, + gdk_fb_pointer_ungrab): Use gdk_fb_window_send_crossing_events. + + * gdk/linux-fb/gdkprivate-fb.h: + removed gdk_fb_window_visibility_crossing, added + gdk_fb_window_send_crossing_events and gdk_fb_find_common_ancestor. + + gdk/linux-fb/gdkwindow-fb.c (gdk_fb_find_common_ancestor): + New function that finds the least common ancestor of two windows. + (gdk_window_show, gdk_window_hide): + Use gdk_fb_window_send_crossing_events. + (gdk_fb_window_move_resize): Send configure events to toplevel + windows. Use gdk_fb_window_send_crossing_events. + 2000-11-27 Havoc Pennington * gtk/gtkprivate.h (enum): Remove a trailing comma diff --git a/gdk/linux-fb/gdkinput-ps2.c b/gdk/linux-fb/gdkinput-ps2.c index 047be8f915..1dfa1b6f19 100644 --- a/gdk/linux-fb/gdkinput-ps2.c +++ b/gdk/linux-fb/gdkinput-ps2.c @@ -121,7 +121,7 @@ send_button_event (MouseDevice *mouse, if (_gdk_fb_pointer_grab_window_events) window = _gdk_fb_pointer_grab_window_events; else - window = gdk_window_get_pointer(NULL, NULL, NULL, NULL); + window = gdk_window_at_pointer(NULL, NULL); gdk_window_get_origin (window, &x, &y); x = mouse->x - x; @@ -411,90 +411,153 @@ move_pointer (MouseDevice *mouse, GdkWindow *in_window) void gdk_fb_cursor_reset(void) { - GdkWindow *win = gdk_window_get_pointer (NULL, NULL, NULL, NULL); + GdkWindow *win = gdk_window_at_pointer (NULL, NULL); move_pointer (gdk_fb_mouse, win); } void -gdk_fb_window_visibility_crossing (GdkWindow *window, - gboolean is_show, - gboolean is_grab) +gdk_fb_window_send_crossing_events (GdkWindow *dest, + GdkCrossingMode mode) { - gint winx, winy; + GdkWindow *c; + GdkWindow *win, *last, *next; + GdkEvent *event; + gint x, y, x_int, y_int; GdkModifierType my_mask; + GList *path, *list; + gboolean non_linear; + GdkWindow *a; + GdkWindow *b; + + if (gdk_fb_mouse->prev_window == NULL) + gdk_fb_mouse->prev_window = gdk_window_ref (gdk_parent_root); - gdk_input_get_mouseinfo (&winx, &winy, &my_mask); + a = gdk_fb_mouse->prev_window; + b = dest; - if (is_grab || - (winx >= GDK_DRAWABLE_IMPL_FBDATA(window)->llim_x && - winx < GDK_DRAWABLE_IMPL_FBDATA(window)->lim_x && - winy >= GDK_DRAWABLE_IMPL_FBDATA(window)->llim_y && - winy < GDK_DRAWABLE_IMPL_FBDATA(window)->lim_y) - ) - { - GdkWindow *oldwin, *newwin, *curwin; - GdkEvent *event; + if (a==b) + return; + + gdk_input_get_mouseinfo (&x, &y, &my_mask); - curwin = gdk_window_get_pointer (NULL, NULL, NULL, NULL); + c = gdk_fb_find_common_ancestor (a, b); - if (is_show) + non_linear = (c != a) && (c != b); + + event = gdk_event_make (a, GDK_LEAVE_NOTIFY, TRUE); + if (event) + { + event->crossing.subwindow = NULL; + gdk_window_get_root_origin (a, &x_int, &y_int); + event->crossing.x = x - x_int; + event->crossing.y = y - y_int; + event->crossing.x_root = x; + event->crossing.y_root = y; + event->crossing.mode = mode; + if (non_linear) + event->crossing.detail = GDK_NOTIFY_NONLINEAR; + else if (c==a) + event->crossing.detail = GDK_NOTIFY_INFERIOR; + else + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + event->crossing.focus = FALSE; + event->crossing.state = my_mask; + } + + /* Traverse up from a to (excluding) c */ + if (c != a) + { + last = a; + win = GDK_WINDOW (GDK_WINDOW_OBJECT (a)->parent); + while (win != c) { - /* Window is about to be shown */ - oldwin = curwin; - newwin = window; + event = gdk_event_make (win, GDK_LEAVE_NOTIFY, TRUE); + if (event) + { + event->crossing.subwindow = gdk_window_ref (last); + gdk_window_get_root_origin (win, &x_int, &y_int); + event->crossing.x = x - x_int; + event->crossing.y = y - y_int; + event->crossing.x_root = x; + event->crossing.y_root = y; + event->crossing.mode = mode; + if (non_linear) + event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; + else + event->crossing.detail = GDK_NOTIFY_VIRTUAL; + event->crossing.focus = FALSE; + event->crossing.state = my_mask; + } + last = win; + win = GDK_WINDOW (GDK_WINDOW_OBJECT (win)->parent); } - else + } + + /* Traverse down from c to b */ + if (c != b) + { + path = NULL; + win = b; + while (win != c) { - /* Window is about to be hidden */ - oldwin = window; - newwin = curwin; + path = g_list_prepend (path, win); + win = GDK_WINDOW( GDK_WINDOW_OBJECT (win)->parent); } - - event = gdk_event_make (oldwin, GDK_LEAVE_NOTIFY, TRUE); - if (event) + + list = path; + while (list) { - guint x_int, y_int; - event->crossing.subwindow = gdk_window_ref (newwin); - gdk_window_get_root_origin (oldwin, &x_int, &y_int); - event->crossing.x = winx - x_int; - event->crossing.y = winy - y_int; - event->crossing.x_root = winx; - event->crossing.y_root = winy; - if (is_grab) + win = (GdkWindow *)list->data; + list = g_list_next (list); + if (list) + next = (GdkWindow *)list->data; + else + next = b; + + event = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE); + if (event) { - if (is_show) - event->crossing.mode = GDK_CROSSING_GRAB; + event->crossing.subwindow = gdk_window_ref (next); + gdk_window_get_root_origin (win, &x_int, &y_int); + event->crossing.x = x - x_int; + event->crossing.y = y - y_int; + event->crossing.x_root = x; + event->crossing.y_root = y; + event->crossing.mode = mode; + if (non_linear) + event->crossing.detail = GDK_NOTIFY_NONLINEAR_VIRTUAL; else - event->crossing.mode = GDK_CROSSING_UNGRAB; + event->crossing.detail = GDK_NOTIFY_VIRTUAL; + event->crossing.focus = FALSE; + event->crossing.state = my_mask; } - else - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - event->crossing.focus = FALSE; - event->crossing.state = my_mask; - } - - event = gdk_event_make (newwin, GDK_ENTER_NOTIFY, TRUE); - if (event) - { - guint x_int, y_int; - event->crossing.subwindow = gdk_window_ref (oldwin); - gdk_window_get_root_origin (newwin, &x_int, &y_int); - event->crossing.x = winx - x_int; - event->crossing.y = winy - y_int; - event->crossing.x_root = winx; - event->crossing.y_root = winy; - event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_UNKNOWN; - event->crossing.focus = FALSE; - event->crossing.state = my_mask; } + g_list_free (path); + } - if (gdk_fb_mouse->prev_window) - gdk_window_unref (gdk_fb_mouse->prev_window); - gdk_fb_mouse->prev_window = gdk_window_ref (newwin); + event = gdk_event_make (b, GDK_ENTER_NOTIFY, TRUE); + if (event) + { + event->crossing.subwindow = NULL; + gdk_window_get_root_origin (b, &x_int, &y_int); + event->crossing.x = x - x_int; + event->crossing.y = y - y_int; + event->crossing.x_root = x; + event->crossing.y_root = y; + event->crossing.mode = mode; + if (non_linear) + event->crossing.detail = GDK_NOTIFY_NONLINEAR; + else if (c==a) + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + else + event->crossing.detail = GDK_NOTIFY_INFERIOR; + event->crossing.focus = FALSE; + event->crossing.state = my_mask; } + + gdk_window_unref (gdk_fb_mouse->prev_window); + gdk_fb_mouse->prev_window = gdk_window_ref (b); } static void @@ -525,7 +588,7 @@ handle_mouse_input(MouseDevice *mouse, if (!got_motion) return; - win = gdk_window_get_pointer (NULL, NULL, NULL, NULL); + win = gdk_window_at_pointer (NULL, NULL); move_pointer (mouse, win); if (_gdk_fb_pointer_grab_window_events) win = _gdk_fb_pointer_grab_window_events; @@ -554,41 +617,8 @@ handle_mouse_input(MouseDevice *mouse, } if (win != mouse->prev_window) - { - GdkEvent *evel; - - if (mouse->prev_window && - (evel = gdk_event_make (mouse->prev_window, GDK_LEAVE_NOTIFY, TRUE))) - { - evel->crossing.subwindow = gdk_window_ref (win); - evel->crossing.x = x; - evel->crossing.y = y; - evel->crossing.x_root = mouse->x; - evel->crossing.y_root = mouse->y; - evel->crossing.mode = GDK_CROSSING_NORMAL; - evel->crossing.detail = GDK_NOTIFY_UNKNOWN; - evel->crossing.focus = FALSE; - evel->crossing.state = state; - } - - evel = gdk_event_make (win, GDK_ENTER_NOTIFY, TRUE); - if (evel) - { - evel->crossing.subwindow = gdk_window_ref (mouse->prev_window ? mouse->prev_window : gdk_parent_root); - evel->crossing.x = x; - evel->crossing.y = y; - evel->crossing.x_root = mouse->x; - evel->crossing.y_root = mouse->y; - evel->crossing.mode = GDK_CROSSING_NORMAL; - evel->crossing.detail = GDK_NOTIFY_UNKNOWN; - evel->crossing.focus = FALSE; - evel->crossing.state = state; - } - - if (mouse->prev_window) - gdk_window_unref (mouse->prev_window); - mouse->prev_window = gdk_window_ref (win); - } + gdk_fb_window_send_crossing_events (win, + GDK_CROSSING_NORMAL); input_activity (); } diff --git a/gdk/linux-fb/gdkmain-fb.c b/gdk/linux-fb/gdkmain-fb.c index b814b30364..9e87f06320 100644 --- a/gdk/linux-fb/gdkmain-fb.c +++ b/gdk/linux-fb/gdkmain-fb.c @@ -626,7 +626,8 @@ gdk_fb_pointer_grab (GdkWindow * window, if (cursor) gdk_fb_cursor_reset (); - gdk_fb_window_visibility_crossing (window, TRUE, TRUE); + gdk_fb_window_send_crossing_events (window, + GDK_CROSSING_GRAB); return GDK_GRAB_SUCCESS; } @@ -656,7 +657,8 @@ void gdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab) { gboolean have_grab_cursor = _gdk_fb_pointer_grab_cursor && 1; - + GdkWindow *mousewin; + if (!_gdk_fb_pointer_grab_window) return; @@ -674,7 +676,9 @@ gdk_fb_pointer_ungrab (guint32 time, gboolean implicit_grab) if (have_grab_cursor) gdk_fb_cursor_reset (); - gdk_fb_window_visibility_crossing (_gdk_fb_pointer_grab_window, FALSE, TRUE); + mousewin = gdk_window_at_pointer (NULL, NULL); + gdk_fb_window_send_crossing_events (mousewin, + GDK_CROSSING_UNGRAB); if (_gdk_fb_pointer_grab_window) gdk_window_unref (_gdk_fb_pointer_grab_window); diff --git a/gdk/linux-fb/gdkprivate-fb.h b/gdk/linux-fb/gdkprivate-fb.h index a07c616604..b8e1b78adb 100644 --- a/gdk/linux-fb/gdkprivate-fb.h +++ b/gdk/linux-fb/gdkprivate-fb.h @@ -264,6 +264,8 @@ void gdk_window_invalidate_region_clear (GdkWindow *window, GdkRegion *region); void gdk_window_invalidate_rect_clear (GdkWindow *window, GdkRectangle *rect); +GdkWindow *gdk_fb_find_common_ancestor (GdkWindow *win1, + GdkWindow *win2); GdkGC * _gdk_fb_gc_new (GdkDrawable *drawable, GdkGCValues *values, @@ -385,8 +387,11 @@ void gdk_fb_cursor_reset(void); void gdk_fb_cursor_hide(void); void gdk_fb_redraw_all(void); -void gdk_input_get_mouseinfo(gint *x, gint *y, GdkModifierType *mask); -void gdk_fb_window_visibility_crossing(GdkWindow *window, gboolean is_show, gboolean is_grab); +void gdk_input_get_mouseinfo (gint *x, + gint *y, + GdkModifierType *mask); +void gdk_fb_window_send_crossing_events (GdkWindow *dest, + GdkCrossingMode mode); #define PANGO_TYPE_FB_FONT (pango_fb_font_get_type ()) #define PANGO_FB_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FB_FONT, PangoFBFont)) diff --git a/gdk/linux-fb/gdkwindow-fb.c b/gdk/linux-fb/gdkwindow-fb.c index ddca101eae..728d17d1ae 100644 --- a/gdk/linux-fb/gdkwindow-fb.c +++ b/gdk/linux-fb/gdkwindow-fb.c @@ -568,11 +568,48 @@ gdk_fb_redraw_all (void) gdk_window_process_all_updates (); } +GdkWindow * +gdk_fb_find_common_ancestor (GdkWindow *win1, + GdkWindow *win2) +{ + GdkWindowObject *tmp; + GList *path1 = NULL, *path2 = NULL; + GList *list1, *list2; + + tmp = GDK_WINDOW_OBJECT (win1); + while (tmp) + { + path1 = g_list_prepend(path1, tmp); + tmp = tmp->parent; + } + + tmp = GDK_WINDOW_OBJECT (win2); + while (tmp) + { + path2 = g_list_prepend(path2, tmp); + tmp = tmp->parent; + } + + list1 = path1; + list2 = path2; + tmp = NULL; + while (list1 && list2 && (list1->data == list2->data)) + { + tmp = (GdkWindowObject *)list1->data; + list1 = g_list_next (list1); + list2 = g_list_next (list2); + } + g_list_free (path1); + g_list_free (path2); + return GDK_WINDOW (tmp); +} + void gdk_window_show (GdkWindow *window) { GdkWindowObject *private; - + GdkWindow *mousewin; + g_return_if_fail (window != NULL); private = (GdkWindowObject*) window; @@ -589,9 +626,9 @@ gdk_window_show (GdkWindow *window) send_map_events (private, TRUE); - private->mapped = FALSE; /* a hack, ayup, to make gdk_window_get_pointer get the other window */ - gdk_fb_window_visibility_crossing (window, TRUE, FALSE); - private->mapped = TRUE; + mousewin = gdk_window_at_pointer (NULL, NULL); + gdk_fb_window_send_crossing_events (mousewin, + GDK_CROSSING_NORMAL); if (private->input_only) return; @@ -609,6 +646,7 @@ void gdk_window_hide (GdkWindow *window) { GdkWindowObject *private; + GdkWindow *mousewin; g_return_if_fail (window != NULL); @@ -632,8 +670,9 @@ gdk_window_hide (GdkWindow *window) if (private->parent == GDK_WINDOW_P(gdk_parent_root)) gdk_fb_drawable_clear(gdk_parent_root); - if (all_parents_shown ((GdkWindowObject *)private->parent)) - gdk_fb_window_visibility_crossing (window, FALSE, FALSE); + mousewin = gdk_window_at_pointer (NULL, NULL); + gdk_fb_window_send_crossing_events (mousewin, + GDK_CROSSING_NORMAL); do_hide = gdk_fb_cursor_need_hide (&r); @@ -781,6 +820,8 @@ gdk_fb_window_move_resize (GdkWindow *window, GdkWindowObject *private; gint dx, dy, dw, dh; gint i, draw_dir; + GdkEvent *event; + GdkWindow *mousewin; g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); @@ -872,6 +913,23 @@ gdk_fb_window_move_resize (GdkWindow *window, gdk_region_destroy (old_region); gdk_region_destroy (new_region); } + /* Send GdkEventConfigure for toplevel windows */ + if (private->window_type != GDK_WINDOW_CHILD) + { + event = gdk_event_make (window, GDK_CONFIGURE, TRUE); + if (event) + { + event->configure.x = private->x; + event->configure.y = private->y; + event->configure.width = GDK_DRAWABLE_IMPL_FBDATA (private)->width; + event->configure.height = GDK_DRAWABLE_IMPL_FBDATA (private)->height; + } + } + + /* The window the pointer is in might have changed */ + mousewin = gdk_window_at_pointer (NULL, NULL); + gdk_fb_window_send_crossing_events (mousewin, + GDK_CROSSING_NORMAL); } } } -- 2.30.2